﻿using System.Collections.Generic;
using System.Linq;
using Missbot.Common;
using Missbot.Service;
using Dolany.UtilityTool;

namespace Missbot.AIModule.OnlineStore
{
    public class ItemCollectionRecord : DbBaseEntity
    {
        public string UserID { get; set; }

        public Dictionary<string, HonorItemCollection> HonorCollections { get; set; } = new();
    }

    public static class ItemCollectionDA
    {
        public static List<string> HonorList(this ItemCollectionRecord entity)
        {
            var honorSvc = AutofacSvc.Resolve<HonorSvc>();
            return entity.HonorCollections
                         .Where(colle => colle.Value.Items.Count == honorSvc.FindHonor(colle.Key).Items.Count)
                         .Select(p => p.Key)
                         .ToList();
        }

        public static Dictionary<string, int> AllItemsDic(this ItemCollectionRecord entity)
        {
            return entity.HonorCollections
                         .Select(p => p.Value)
                         .SelectMany(p => p.Items)
                         .ToDictionary(p => p.Key, p => p.Value);
        }

        public static ItemCollectionRecord Get(string UserID)
        {
            var record = MongoService<ItemCollectionRecord>.GetOnly(p => p.UserID == UserID);
            if (record != null)
            {
                return record;
            }

            record = new ItemCollectionRecord
            {
                UserID = UserID
            };
            MongoService<ItemCollectionRecord>.Insert(record);
            return record;
        }

        public static List<ItemCollectionRecord> GetByHonor(string honorName)
        {
            return MongoService<ItemCollectionRecord>.Get(r => r.HonorCollections.ContainsKey(honorName));
        }
        
        public static IEnumerable<ItemCollectionRecord> GetByHonorAndItem(string honorName, string itemName)
        {
            return MongoService<ItemCollectionRecord>.Get(p => p.HonorCollections != null &&
                                                               p.HonorCollections.ContainsKey(honorName) &&
                                                               p.HonorCollections[honorName].Items.ContainsKey(itemName));
        }

        public static void ItemConsume(this ItemCollectionRecord entity, string name, int count = 1)
        {
            var collection = entity.HonorCollections.First(p => p.Value.Items.Any(i => i.Key == name));
            collection.Value.Items[name] -= count;
        }

        public static void ItemConsume(this ItemCollectionRecord entity, Dictionary<string, int> itemDic)
        {
            if (itemDic.IsNullOrEmpty())
            {
                return;
            }

            foreach (var (key, value) in itemDic)
            {
                entity.ItemConsume(key, value);
            }
        }

        public static bool CheckItem(this ItemCollectionRecord entity, string itemName, int count = 1)
        {
            return entity.HonorCollections.Values.Any(p => p.Items.ContainsKey(itemName) && p.Items[itemName] >= count);
        }

        public static bool CheckItem(this ItemCollectionRecord entity, Dictionary<string, int> itemDic)
        {
            return itemDic.All(p => entity.CheckItem(p.Key, p.Value));
        }

        public static int GetCount(this ItemCollectionRecord entity, string itemName)
        {
            var collection = entity.HonorCollections.Values.FirstOrDefault(p => p.Items.ContainsKey(itemName));
            return collection?.Items[itemName] ?? 0;
        }

        public static int TotalItemCount(this ItemCollectionRecord entity)
        {
            return entity.HonorCollections.Values.Sum(p => p.Items.Sum(i => i.Value));
        }

        public static void Update(this ItemCollectionRecord entity)
        {
            foreach (var (_, value) in entity.HonorCollections)
            {
                value.Items.Remove(p => p == 0);
            }

            entity.HonorCollections.Remove(p => p.Items.IsNullOrEmpty());
            MongoService<ItemCollectionRecord>.Update(entity);
        }

        public static int AssertToGold(this ItemCollectionRecord entity)
        {
            var itemAssert = 0;
            var HonorHelper = AutofacSvc.Resolve<HonorSvc>();
            foreach (var (honorName, collection) in entity.HonorCollections)
            {
                var honorModel = HonorHelper.FindHonor(honorName);
                var honorPrice = honorModel.Items.Sum(p => p.Price) * 3 / 2;
                while (collection.Items != null && honorModel.Items.Count == collection.Items.Count)
                {
                    itemAssert += honorPrice;

                    for (var i = 0; i < collection.Items.Count; i++)
                    {
                        collection.Items[collection.Items.Keys.ElementAt(i)]--;
                    }

                    collection.Items.Remove(p => p == 0);
                }

                itemAssert += collection.Items?.Sum(p => honorModel.Items.First(item => item.Name == p.Key).Price * p.Value) ?? 0;
            }

            return itemAssert;
        }
    }

    public class HonorItemCollection
    {
        public string Name { get; set; }

        public HonorType Type { get; init; }

        public Dictionary<string, int> Items { get; set; } = new();
    }

    public enum HonorType
    {
        Normal = 0,
        Limit = 1,
        Special = 2
    }
}